package com.kujie.langchain4j.utils;

import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.impl.DefaultRedirectStrategy;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.*;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.*;
import org.springframework.web.util.UriComponentsBuilder;

import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

/**
 * HTTP 请求工具类 (静态方法版本)
 * 基于 Spring Boot 3.4.1 的 RestClient
 *
 * @author jyy
 * @date 2025-05-22
 */
public class HttpUtils {
    private static final Logger logger = LoggerFactory.getLogger(HttpUtils.class);

    /**
     * http客户端 使用volatile保证可见性
     */
    private static volatile RestClient REST_CLIENT;

    /**
     * 默认连接超时时间
     */
    private static final int DEFAULT_CONNECT_TIMEOUT = 5000;

    /**
     * 默认读取超时时间
     */
    private static final int DEFAULT_READ_TIMEOUT = 10000;

    /**
     * 默认最大重试次数
     */
    private static final int DEFAULT_MAX_RETRIES = 3;

    /**
     * 私有构造器
     */
    private HttpUtils() {
    }

    /**
     * 初始化(使用默认配置)
     */
    public static synchronized void init() {
        init(DEFAULT_CONNECT_TIMEOUT, DEFAULT_READ_TIMEOUT, DEFAULT_MAX_RETRIES);
    }

    /**
     * 自定义初始化
     *
     * @param connectTimeout 连接超时时间
     * @param readTimeout    读取超时时间
     * @param maxRetries     最大重试次数
     */
    public static synchronized void init(int connectTimeout, int readTimeout, int maxRetries) {
        if (REST_CLIENT != null) {
            logger.warn("HttpUtils已经初始化过，本次初始化将被忽略");
            return;
        }

        // 创建HTTP配置
        RequestConfig config = RequestConfig.custom()
                .setConnectTimeout(connectTimeout, TimeUnit.MILLISECONDS)
                .setResponseTimeout(readTimeout, TimeUnit.MILLISECONDS)
                .build();

        // 创建HTTP客户端
        CloseableHttpClient httpClient = HttpClientBuilder.create()
                .setDefaultRequestConfig(config)
                .setRedirectStrategy(new DefaultRedirectStrategy())
                .build();

        // 创建请求工厂
        HttpComponentsClientHttpRequestFactory factory =
                new HttpComponentsClientHttpRequestFactory(httpClient);
        factory.setConnectTimeout(connectTimeout);
        factory.setReadTimeout(readTimeout);

        // 构建RestClient
        REST_CLIENT = RestClient.builder()
                .requestFactory(factory)
                .defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
                .requestInterceptor((request, body, execution) -> {
                    if (logger.isDebugEnabled()) {
                        logger.debug("HTTP请求 {} => {}\n头信息: {}\n请求体: {}",
                                request.getMethod(), request.getURI(),
                                request.getHeaders(), body != null ? new String(body) : "null");
                    }
                    return execution.execute(request, body);
                })
                .requestInterceptor((request, body, execution) -> {
                    long start = System.currentTimeMillis();
                    try {
                        ClientHttpResponse response = execution.execute(request, body);
                        if (logger.isDebugEnabled()) {
                            long duration = System.currentTimeMillis() - start;
                            logger.debug("HTTP响应 {} <= {} - 状态: {} - 耗时: {}ms",
                                    request.getMethod(), request.getURI(),
                                    response.getStatusCode(), duration);
                        }
                        return response;
                    } catch (RestClientResponseException e) {
                        logger.error("HTTP请求失败，状态码 {}: {}",
                                e.getStatusCode(), e.getResponseBodyAsString());
                        throw e;
                    }
                })
                .requestInterceptor((request, body, execution) -> {
                    int retryCount = 0;
                    while (true) {
                        try {
                            return execution.execute(request, body);
                        } catch (RestClientException e) {
                            if (retryCount++ >= maxRetries) {
                                throw e;
                            }
                            logger.warn("请求失败(第{}/{}次尝试)，正在重试...", retryCount, maxRetries);
                            try {
                                TimeUnit.SECONDS.sleep(1);
                            } catch (InterruptedException ie) {
                                Thread.currentThread().interrupt();
                                throw new RuntimeException("重试过程中被中断", ie);
                            }
                        }
                    }
                })
                .build();
    }


    // ========== 静态请求方法 ==========

    /**
     * 执行GET请求
     *
     * @param url          请求URL
     * @param headers      请求头Map (可为null)
     * @param responseType 响应体类型
     * @param <T>          响应体泛型类型
     * @return 包含响应体和状态码的ResponseEntity
     * @throws HttpRequestException 当请求失败时抛出
     */
    public static <T> ResponseEntity<T> get(String url,
                                            Map<String, String> headers,
                                            ParameterizedTypeReference<T> responseType) {
        return executeRequest(REST_CLIENT, HttpMethod.GET, url, headers, null, null, null, responseType);
    }

    /**
     * 执行GET请求
     *
     * @param url          请求URL
     * @param headers      请求头Map (可为null)
     * @param query        请求参数Map (可为null)
     * @param responseType 响应体类型
     * @param <T>          响应体泛型类型
     * @return 包含响应体和状态码的ResponseEntity
     * @throws HttpRequestException 当请求失败时抛出
     */
    public static <T> ResponseEntity<T> get(String url,
                                            Map<String, String> headers,
                                            Map<String, ?> query,
                                            ParameterizedTypeReference<T> responseType) {
        return executeRequest(REST_CLIENT, HttpMethod.GET, url, headers, null, query, null, responseType);
    }

    /**
     * 执行GET请求
     *
     * @param url          请求URL
     * @param headers      请求头Map (可为null)
     * @param uriVariables 请求参数Map (可为null)
     * @param query        请求参数Map (可为null)
     * @param body         请求体 (可为null)
     * @param responseType 响应体类型
     * @param <T>          响应体泛型类型
     * @return 包含响应体和状态码的ResponseEntity
     * @throws HttpRequestException 当请求失败时抛出
     */
    public static <T> ResponseEntity<T> get(String url,
                                            Map<String, String> headers,
                                            Map<String, ?> uriVariables,
                                            Map<String, ?> query,
                                            Object body,
                                            ParameterizedTypeReference<T> responseType) {
        return executeRequest(REST_CLIENT, HttpMethod.GET, url, headers, uriVariables, query, body, responseType);
    }

    /**
     * 执行POST请求
     *
     * @param url          请求URL
     * @param headers      请求头Map (可为null)
     * @param responseType 响应体类型
     * @param <T>          响应体泛型类型
     * @return 包含响应体和状态码的ResponseEntity
     * @throws HttpRequestException 当请求失败时抛出
     */
    public static <T> ResponseEntity<T> post(String url,
                                             Map<String, String> headers,
                                             ParameterizedTypeReference<T> responseType) {
        return executeRequest(REST_CLIENT, HttpMethod.POST, url, headers, null, null, null, responseType);
    }


    /**
     * 执行POST请求
     *
     * @param url          请求URL
     * @param headers      请求头Map (可为null)
     * @param body         请求体 (可为null)
     * @param responseType 响应体类型
     * @param <T>          响应体泛型类型
     * @return 包含响应体和状态码的ResponseEntity
     * @throws HttpRequestException 当请求失败时抛出
     */
    public static <T> ResponseEntity<T> post(String url,
                                             Map<String, String> headers,
                                             Object body,
                                             ParameterizedTypeReference<T> responseType) {
        return executeRequest(REST_CLIENT, HttpMethod.POST, url, headers, null, null, body, responseType);
    }

    /**
     * 执行POST请求
     *
     * @param url          请求URL
     * @param headers      请求头Map (可为null)
     * @param uriVariables 请求参数Map (可为null)
     * @param query        请求参数Map (可为null)
     * @param body         请求体 (可为null)
     * @param responseType 响应体类型
     * @param <T>          响应体泛型类型
     * @return 包含响应体和状态码的ResponseEntity
     * @throws HttpRequestException 当请求失败时抛出
     */
    public static <T> ResponseEntity<T> post(String url,
                                             Map<String, String> headers,
                                             Map<String, ?> uriVariables,
                                             Map<String, ?> query,
                                             Object body,
                                             ParameterizedTypeReference<T> responseType) {
        return executeRequest(REST_CLIENT, HttpMethod.POST, url, headers, uriVariables, query, body, responseType);
    }

    /**
     * 执行PUT请求
     *
     * @param url          请求URL
     * @param body         请求体对象 (可为null)
     * @param responseType 响应体类型
     * @param <T>          响应体泛型类型
     * @return 包含响应体和状态码的ResponseEntity
     * @throws HttpRequestException 当请求失败时抛出
     */
    public static <T> ResponseEntity<T> put(String url,
                                            Map<String, String> headers,
                                            Object body,
                                            ParameterizedTypeReference<T> responseType) {
        return executeRequest(REST_CLIENT, HttpMethod.PUT, url, headers, null, null, body, responseType);
    }

    /**
     * 执行PUT请求
     *
     * @param url          请求URL
     * @param headers      请求头Map (可为null)
     * @param uriVariables 请求参数Map (可为null)
     * @param query        请求参数Map (可为null)
     * @param body         请求体 (可为null)
     * @param responseType 响应体类型
     * @param <T>          响应体泛型类型
     * @return 包含响应体和状态码的ResponseEntity
     * @throws HttpRequestException 当请求失败时抛出
     */
    public static <T> ResponseEntity<T> put(String url,
                                            Map<String, String> headers,
                                            Map<String, ?> uriVariables,
                                            Map<String, ?> query,
                                            Object body,
                                            ParameterizedTypeReference<T> responseType) {
        return executeRequest(REST_CLIENT, HttpMethod.PUT, url, headers, uriVariables, query, body, responseType);
    }

    /**
     * 执行DELETE请求
     *
     * @param url          请求URL
     * @param headers      请求头Map (可为null)
     * @param uriVariables 请求参数Map (可为null)
     * @param responseType 响应体类型
     * @param <T>          响应体泛型类型
     * @return 包含响应体和状态码的ResponseEntity
     * @throws HttpRequestException 当请求失败时抛出
     */
    public static <T> ResponseEntity<T> delete(String url,
                                               Map<String, String> headers,
                                               Map<String, ?> uriVariables,
                                               ParameterizedTypeReference<T> responseType) {
        return executeRequest(REST_CLIENT, HttpMethod.DELETE, url, headers, uriVariables, null, null, responseType);
    }

    /**
     * 执行DELETE请求
     *
     * @param url          请求URL
     * @param responseType 响应体类型
     * @param headers      请求头Map (可为null)
     * @param body         请求体 (可为null)
     * @param <T>          响应体泛型类型
     * @return 包含响应体和状态码的ResponseEntity
     * @throws HttpRequestException 当请求失败时抛出
     */
    public static <T> ResponseEntity<T> delete(String url,
                                               Map<String, String> headers,
                                               Object body,
                                               ParameterizedTypeReference<T> responseType) {
        return executeRequest(REST_CLIENT, HttpMethod.DELETE, url, headers, null, null, body, responseType);
    }

    /**
     * 执行DELETE请求
     *
     * @param url          请求URL
     * @param headers      请求头Map (可为null)
     * @param uriVariables 请求参数Map (可为null)
     * @param query        请求参数Map (可为null)
     * @param body         请求体 (可为null)
     * @param responseType 响应体类型
     * @param <T>          响应体泛型类型
     * @return 包含响应体和状态码的ResponseEntity
     * @throws HttpRequestException 当请求失败时抛出
     */
    public static <T> ResponseEntity<T> delete(String url,
                                               Map<String, String> headers,
                                               Map<String, ?> uriVariables,
                                               Map<String, ?> query,
                                               Object body,
                                               ParameterizedTypeReference<T> responseType) {
        return executeRequest(REST_CLIENT, HttpMethod.DELETE, url, headers, uriVariables, query, body, responseType);
    }

    /**
     * 执行文件上传(POST)
     *
     * @param url           请求URL
     * @param headers       请求头Map (可为null)
     * @param fileParamName 文件参数名
     * @param file          要上传的文件
     * @param responseType  响应体类型
     * @param <T>           响应体泛型类型
     * @return 包含响应体和状态码的ResponseEntity
     * @throws HttpRequestException     当请求失败时抛出
     * @throws IllegalArgumentException 当文件为null时抛出
     */
    public static <T> ResponseEntity<T> upload(String url,
                                               Map<String, String> headers,
                                               String fileParamName,
                                               File file,
                                               ParameterizedTypeReference<T> responseType) {
        MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
        body.add(fileParamName, new FileSystemResource(file));
        return executeRequest(REST_CLIENT, HttpMethod.POST, url, headers, null, null, body, responseType);
    }

    /**
     * 执行GET请求
     *
     * @param url          请求URL
     * @param headers      请求头Map (可为null)
     * @param responseType 响应体类型
     * @param <T>          响应体泛型类型
     * @return 包含响应体和状态码的ResponseEntity
     * @throws HttpRequestException 当请求失败时抛出
     */
    public static <T> ResponseEntity<T> get(String url,
                                            Map<String, String> headers,
                                            Class<T> responseType) {
        return executeRequest(REST_CLIENT, HttpMethod.GET, url, headers, null, null, null, responseType);
    }

    /**
     * 执行GET请求
     *
     * @param url          请求URL
     * @param headers      请求头Map (可为null)
     * @param query        请求参数Map (可为null)
     * @param responseType 响应体类型
     * @param <T>          响应体泛型类型
     * @return 包含响应体和状态码的ResponseEntity
     * @throws HttpRequestException 当请求失败时抛出
     */
    public static <T> ResponseEntity<T> get(String url,
                                            Map<String, String> headers,
                                            Map<String, ?> query,
                                            Class<T> responseType) {
        return executeRequest(REST_CLIENT, HttpMethod.GET, url, headers, null, query, null, responseType);
    }

    /**
     * 执行GET请求
     *
     * @param url          请求URL
     * @param headers      请求头Map (可为null)
     * @param uriVariables 请求参数Map (可为null)
     * @param query        请求参数Map (可为null)
     * @param body         请求体 (可为null)
     * @param responseType 响应体类型
     * @param <T>          响应体泛型类型
     * @return 包含响应体和状态码的ResponseEntity
     * @throws HttpRequestException 当请求失败时抛出
     */
    public static <T> ResponseEntity<T> get(String url,
                                            Map<String, String> headers,
                                            Map<String, ?> uriVariables,
                                            Map<String, ?> query,
                                            Object body,
                                            Class<T> responseType) {
        return executeRequest(REST_CLIENT, HttpMethod.GET, url, headers, uriVariables, query, body, responseType);
    }

    /**
     * 执行POST请求
     *
     * @param url          请求URL
     * @param headers      请求头Map (可为null)
     * @param responseType 响应体类型
     * @param <T>          响应体泛型类型
     * @return 包含响应体和状态码的ResponseEntity
     * @throws HttpRequestException 当请求失败时抛出
     */
    public static <T> ResponseEntity<T> post(String url,
                                             Map<String, String> headers,
                                             Class<T> responseType) {
        return executeRequest(REST_CLIENT, HttpMethod.POST, url, headers, null, null, null, responseType);
    }


    /**
     * 执行POST请求
     *
     * @param url          请求URL
     * @param headers      请求头Map (可为null)
     * @param body         请求体 (可为null)
     * @param responseType 响应体类型
     * @param <T>          响应体泛型类型
     * @return 包含响应体和状态码的ResponseEntity
     * @throws HttpRequestException 当请求失败时抛出
     */
    public static <T> ResponseEntity<T> post(String url,
                                             Map<String, String> headers,
                                             Object body,
                                             Class<T> responseType) {
        return executeRequest(REST_CLIENT, HttpMethod.POST, url, headers, null, null, body, responseType);
    }

    /**
     * 执行POST请求
     *
     * @param url          请求URL
     * @param headers      请求头Map (可为null)
     * @param uriVariables 请求参数Map (可为null)
     * @param query        请求参数Map (可为null)
     * @param body         请求体 (可为null)
     * @param responseType 响应体类型
     * @param <T>          响应体泛型类型
     * @return 包含响应体和状态码的ResponseEntity
     * @throws HttpRequestException 当请求失败时抛出
     */
    public static <T> ResponseEntity<T> post(String url,
                                             Map<String, String> headers,
                                             Map<String, ?> uriVariables,
                                             Map<String, ?> query,
                                             Object body,
                                             Class<T> responseType) {
        return executeRequest(REST_CLIENT, HttpMethod.POST, url, headers, uriVariables, query, body, responseType);
    }

    /**
     * 执行PUT请求
     *
     * @param url          请求URL
     * @param body         请求体对象 (可为null)
     * @param responseType 响应体类型
     * @param <T>          响应体泛型类型
     * @return 包含响应体和状态码的ResponseEntity
     * @throws HttpRequestException 当请求失败时抛出
     */
    public static <T> ResponseEntity<T> put(String url,
                                            Map<String, String> headers,
                                            Object body,
                                            Class<T> responseType) {
        return executeRequest(REST_CLIENT, HttpMethod.PUT, url, headers, null, null, body, responseType);
    }

    /**
     * 执行PUT请求
     *
     * @param url          请求URL
     * @param headers      请求头Map (可为null)
     * @param uriVariables 请求参数Map (可为null)
     * @param query        请求参数Map (可为null)
     * @param body         请求体 (可为null)
     * @param responseType 响应体类型
     * @param <T>          响应体泛型类型
     * @return 包含响应体和状态码的ResponseEntity
     * @throws HttpRequestException 当请求失败时抛出
     */
    public static <T> ResponseEntity<T> put(String url,
                                            Map<String, String> headers,
                                            Map<String, ?> uriVariables,
                                            Map<String, ?> query,
                                            Object body,
                                            Class<T> responseType) {
        return executeRequest(REST_CLIENT, HttpMethod.PUT, url, headers, uriVariables, query, body, responseType);
    }

    /**
     * 执行DELETE请求
     *
     * @param url          请求URL
     * @param headers      请求头Map (可为null)
     * @param uriVariables 请求参数Map (可为null)
     * @param responseType 响应体类型
     * @param <T>          响应体泛型类型
     * @return 包含响应体和状态码的ResponseEntity
     * @throws HttpRequestException 当请求失败时抛出
     */
    public static <T> ResponseEntity<T> delete(String url,
                                               Map<String, String> headers,
                                               Map<String, ?> uriVariables,
                                               Class<T> responseType) {
        return executeRequest(REST_CLIENT, HttpMethod.DELETE, url, headers, uriVariables, null, null, responseType);
    }

    /**
     * 执行DELETE请求
     *
     * @param url          请求URL
     * @param responseType 响应体类型
     * @param headers      请求头Map (可为null)
     * @param body         请求体 (可为null)
     * @param <T>          响应体泛型类型
     * @return 包含响应体和状态码的ResponseEntity
     * @throws HttpRequestException 当请求失败时抛出
     */
    public static <T> ResponseEntity<T> delete(String url,
                                               Map<String, String> headers,
                                               Object body,
                                               Class<T> responseType) {
        return executeRequest(REST_CLIENT, HttpMethod.DELETE, url, headers, null, null, body, responseType);
    }

    /**
     * 执行DELETE请求
     *
     * @param url          请求URL
     * @param headers      请求头Map (可为null)
     * @param uriVariables 请求参数Map (可为null)
     * @param query        请求参数Map (可为null)
     * @param body         请求体 (可为null)
     * @param responseType 响应体类型
     * @param <T>          响应体泛型类型
     * @return 包含响应体和状态码的ResponseEntity
     * @throws HttpRequestException 当请求失败时抛出
     */
    public static <T> ResponseEntity<T> delete(String url,
                                               Map<String, String> headers,
                                               Map<String, ?> uriVariables,
                                               Map<String, ?> query,
                                               Object body,
                                               Class<T> responseType) {
        return executeRequest(REST_CLIENT, HttpMethod.DELETE, url, headers, uriVariables, query, body, responseType);
    }

    /**
     * 执行文件上传(POST)
     *
     * @param url           请求URL
     * @param headers       请求头Map (可为null)
     * @param fileParamName 文件参数名
     * @param file          要上传的文件
     * @param responseType  响应体类型
     * @param <T>           响应体泛型类型
     * @return 包含响应体和状态码的ResponseEntity
     * @throws HttpRequestException     当请求失败时抛出
     * @throws IllegalArgumentException 当文件为null时抛出
     */
    public static <T> ResponseEntity<T> upload(String url,
                                               Map<String, String> headers,
                                               String fileParamName,
                                               File file,
                                               Class<T> responseType) {
        MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
        body.add(fileParamName, new FileSystemResource(file));
        return executeRequest(REST_CLIENT, HttpMethod.POST, url, headers, null, null, body, responseType);
    }


    // ========== 异步静态方法 ==========

    /**
     * 异步执行GET请求
     *
     * @param url          请求URL
     * @param headers      请求头Map (可为null)
     * @param responseType 响应体类型
     * @param <T>          响应体泛型类型
     * @return CompletableFuture包装的ResponseEntity
     */
    public static <T> CompletableFuture<ResponseEntity<T>> getAsync(String url,
                                                                    Map<String, String> headers,
                                                                    ParameterizedTypeReference<T> responseType) {
        return CompletableFuture.supplyAsync(() ->
                get(url, headers, responseType), ThreadPoolUtils.getDefaultExecutor());
    }

    /**
     * 异步执行GET请求
     *
     * @param url          请求URL
     * @param headers      请求头Map (可为null)
     * @param query        请求参数Map (可为null)
     * @param responseType 响应体类型
     * @param <T>          响应体泛型类型
     * @return CompletableFuture包装的ResponseEntity
     */
    public static <T> CompletableFuture<ResponseEntity<T>> getAsync(String url,
                                                                    Map<String, String> headers,
                                                                    Map<String, ?> query,
                                                                    ParameterizedTypeReference<T> responseType) {
        return CompletableFuture.supplyAsync(() ->
                get(url, headers, query, responseType), ThreadPoolUtils.getDefaultExecutor());
    }

    /**
     * 异步执行GET请求
     *
     * @param url          请求URL
     * @param headers      请求头Map (可为null)
     * @param uriVariables 请求参数Map (可为null)
     * @param query        请求参数Map (可为null)
     * @param body         请求体 (可为null)
     * @param responseType 响应体类型
     * @param <T>          响应体泛型类型
     * @return 包含响应体和状态码的ResponseEntity
     * @throws HttpRequestException 当请求失败时抛出
     */
    public static <T> CompletableFuture<ResponseEntity<T>> getAsync(String url,
                                                                    Map<String, String> headers,
                                                                    Map<String, ?> uriVariables,
                                                                    Map<String, ?> query,
                                                                    Object body,
                                                                    ParameterizedTypeReference<T> responseType) {
        return CompletableFuture.supplyAsync(() ->
                get(url, headers, uriVariables, query, body, responseType), ThreadPoolUtils.getDefaultExecutor());
    }

    /**
     * 异步执行POST请求
     *
     * @param url          请求URL
     * @param headers      请求头Map (可为null)
     * @param responseType 响应体类型
     * @param <T>          响应体泛型类型
     * @return 包含响应体和状态码的ResponseEntity
     * @throws HttpRequestException 当请求失败时抛出
     */
    public static <T> CompletableFuture<ResponseEntity<T>> postAsync(String url,
                                                                     Map<String, String> headers,
                                                                     ParameterizedTypeReference<T> responseType) {
        return CompletableFuture.supplyAsync(() ->
                post(url, headers, responseType), ThreadPoolUtils.getDefaultExecutor());
    }


    /**
     * 异步执行POST请求
     *
     * @param url          请求URL
     * @param headers      请求头Map (可为null)
     * @param body         请求体 (可为null)
     * @param responseType 响应体类型
     * @param <T>          响应体泛型类型
     * @return 包含响应体和状态码的ResponseEntity
     * @throws HttpRequestException 当请求失败时抛出
     */
    public static <T> CompletableFuture<ResponseEntity<T>> postAsync(String url,
                                                                     Map<String, String> headers,
                                                                     Object body,
                                                                     ParameterizedTypeReference<T> responseType) {
        return CompletableFuture.supplyAsync(() ->
                post(url, headers, body, responseType), ThreadPoolUtils.getDefaultExecutor());
    }

    /**
     * 异步执行POST请求
     *
     * @param url          请求URL
     * @param headers      请求头Map (可为null)
     * @param uriVariables 请求参数Map (可为null)
     * @param query        请求参数Map (可为null)
     * @param body         请求体 (可为null)
     * @param responseType 响应体类型
     * @param <T>          响应体泛型类型
     * @return 包含响应体和状态码的ResponseEntity
     * @throws HttpRequestException 当请求失败时抛出
     */
    public static <T> CompletableFuture<ResponseEntity<T>> postAsync(String url,
                                                                     Map<String, String> headers,
                                                                     Map<String, ?> uriVariables,
                                                                     Map<String, ?> query,
                                                                     Object body,
                                                                     ParameterizedTypeReference<T> responseType) {
        return CompletableFuture.supplyAsync(() ->
                post(url, headers, uriVariables, query, body, responseType), ThreadPoolUtils.getDefaultExecutor());
    }

    /**
     * 异步执行GET请求
     *
     * @param url          请求URL
     * @param headers      请求头Map (可为null)
     * @param responseType 响应体类型
     * @param <T>          响应体泛型类型
     * @return CompletableFuture包装的ResponseEntity
     */
    public static <T> CompletableFuture<ResponseEntity<T>> getAsync(String url,
                                                                    Map<String, String> headers,
                                                                    Class<T> responseType) {
        return CompletableFuture.supplyAsync(() ->
                get(url, headers, responseType), ThreadPoolUtils.getDefaultExecutor());
    }

    /**
     * 异步执行GET请求
     *
     * @param url          请求URL
     * @param headers      请求头Map (可为null)
     * @param query        请求参数Map (可为null)
     * @param responseType 响应体类型
     * @param <T>          响应体泛型类型
     * @return CompletableFuture包装的ResponseEntity
     */
    public static <T> CompletableFuture<ResponseEntity<T>> getAsync(String url,
                                                                    Map<String, String> headers,
                                                                    Map<String, ?> query,
                                                                    Class<T> responseType) {
        return CompletableFuture.supplyAsync(() ->
                get(url, headers, query, responseType), ThreadPoolUtils.getDefaultExecutor());
    }

    /**
     * 异步执行GET请求
     *
     * @param url          请求URL
     * @param headers      请求头Map (可为null)
     * @param uriVariables 请求参数Map (可为null)
     * @param query        请求参数Map (可为null)
     * @param body         请求体 (可为null)
     * @param responseType 响应体类型
     * @param <T>          响应体泛型类型
     * @return 包含响应体和状态码的ResponseEntity
     * @throws HttpRequestException 当请求失败时抛出
     */
    public static <T> CompletableFuture<ResponseEntity<T>> getAsync(String url,
                                                                    Map<String, String> headers,
                                                                    Map<String, ?> uriVariables,
                                                                    Map<String, ?> query,
                                                                    Object body,
                                                                    Class<T> responseType) {
        return CompletableFuture.supplyAsync(() ->
                get(url, headers, uriVariables, query, body, responseType), ThreadPoolUtils.getDefaultExecutor());
    }

    /**
     * 异步执行POST请求
     *
     * @param url          请求URL
     * @param headers      请求头Map (可为null)
     * @param responseType 响应体类型
     * @param <T>          响应体泛型类型
     * @return 包含响应体和状态码的ResponseEntity
     * @throws HttpRequestException 当请求失败时抛出
     */
    public static <T> CompletableFuture<ResponseEntity<T>> postAsync(String url,
                                                                     Map<String, String> headers,
                                                                     Class<T> responseType) {
        return CompletableFuture.supplyAsync(() ->
                post(url, headers, responseType), ThreadPoolUtils.getDefaultExecutor());
    }


    /**
     * 异步执行POST请求
     *
     * @param url          请求URL
     * @param headers      请求头Map (可为null)
     * @param body         请求体 (可为null)
     * @param responseType 响应体类型
     * @param <T>          响应体泛型类型
     * @return 包含响应体和状态码的ResponseEntity
     * @throws HttpRequestException 当请求失败时抛出
     */
    public static <T> CompletableFuture<ResponseEntity<T>> postAsync(String url,
                                                                     Map<String, String> headers,
                                                                     Object body,
                                                                     Class<T> responseType) {
        return CompletableFuture.supplyAsync(() ->
                post(url, headers, body, responseType), ThreadPoolUtils.getDefaultExecutor());
    }

    /**
     * 异步执行POST请求
     *
     * @param url          请求URL
     * @param headers      请求头Map (可为null)
     * @param uriVariables 请求参数Map (可为null)
     * @param query        请求参数Map (可为null)
     * @param body         请求体 (可为null)
     * @param responseType 响应体类型
     * @param <T>          响应体泛型类型
     * @return 包含响应体和状态码的ResponseEntity
     * @throws HttpRequestException 当请求失败时抛出
     */
    public static <T> CompletableFuture<ResponseEntity<T>> postAsync(String url,
                                                                     Map<String, String> headers,
                                                                     Map<String, ?> uriVariables,
                                                                     Map<String, ?> query,
                                                                     Object body,
                                                                     Class<T> responseType) {
        return CompletableFuture.supplyAsync(() ->
                post(url, headers, uriVariables, query, body, responseType), ThreadPoolUtils.getDefaultExecutor());
    }

    // ========== 核心执行方法 ==========

    /**
     * 将查询参数添加到URL中，构建完整的请求URL。
     * 如果原始URL已包含查询参数，新的参数会被追加。
     *
     * @param url    原始URL
     * @param params 查询参数Map，key为参数名，value为参数值
     * @return 带有查询参数的完整URL
     */
    private static String buildUrlWithParams(String url, Map<String, ?> params) {
        // 如果没有查询参数，直接返回原始URL
        if (CollectionUtils.isEmpty(params)) {
            return url;
        }

        // 使用 UriComponentsBuilder 安全地构建URL
        UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromUriString(url);

        // 添加所有非空的查询参数
        params.forEach((key, value) -> {
            if (value != null) {
                uriBuilder.queryParam(key, value);
            }
        });

        // 构建并返回完整的URL字符串
        return uriBuilder.build().toUriString();
    }

    /**
     * 构建并配置一个 RestClient 的 RequestBodySpec 对象，用于发送 HTTP 请求。
     * 支持路径参数、查询参数、请求头和请求体的设置。
     *
     * @param client       RestClient 实例
     * @param url          请求URL，可以包含路径变量（如 {id}）
     * @param method       HTTP 方法（GET, POST, PUT, DELETE 等）
     * @param headers      请求头 Map，key 为头名称，value 为头值
     * @param body         请求体内容，可以是任意对象或 MultiValueMap（用于表单提交）
     * @param query        查询参数 Map，key 为参数名，value 为参数值
     * @param uriVariables 路径变量 Map，用于替换 URL 中的路径参数（如 {id}）
     * @return 配置好的 RequestBodySpec 对象，可以进一步自定义或直接执行
     * @throws IllegalArgumentException 如果 URL 或 HTTP 方法无效
     */
    private static RestClient.RequestBodySpec getRequestBodySpec(RestClient client,
                                                                 HttpMethod method,
                                                                 String url,
                                                                 Map<String, String> headers,
                                                                 Map<String, ?> uriVariables,
                                                                 Map<String, ?> query,
                                                                 Object body) {
        // 构建带有查询参数的完整URL
        String finalUrl = buildUrlWithParams(url, query);

        // 创建基础请求，设置方法和URL（包含路径变量替换）
        RestClient.RequestBodySpec request = client
                .method(method)
                .uri(finalUrl, CollectionUtils.isEmpty(uriVariables) ? Map.of() : uriVariables);

        // 添加请求头（如果提供了）
        if (headers != null && !headers.isEmpty()) {
            headers.forEach(request::header);
        }

        /*
         * 设置请求体相关内容：
         * 1. 如果请求体不为空且未明确设置 Content-Type 头
         * 2. 根据请求体类型自动设置合适的 Content-Type：
         *    - MultiValueMap: multipart/form-data
         *    - Resource: 不自动设置（通常由框架处理）
         *    - 其他类型: application/json
         */
        if (body != null && (headers == null || !headers.containsKey(HttpHeaders.CONTENT_TYPE))) {
            if (body instanceof MultiValueMap) {
                request.contentType(MediaType.MULTIPART_FORM_DATA);
            } else if (!(body instanceof Resource)) {
                request.contentType(MediaType.APPLICATION_JSON);
            }
        }

        // 设置请求体（如果提供了）
        if (body != null) {
            request.body(body);
        }

        return request;
    }

    /**
     * 执行HTTP请求核心方法
     *
     * @param client       RestClient实例
     * @param method       HTTP方法
     * @param url          请求URL
     * @param headers      请求头Map (可为null)
     * @param uriVariables URI变量Map (可为null)
     * @param query        请求参数Map (可为null)
     * @param body         请求体对象 (可为null)
     * @param responseType 响应体类型
     * @param <T>          响应体泛型类型
     * @return 包含响应体和状态码的ResponseEntity
     * @throws HttpRequestException 当请求失败时抛出
     */
    private static <T> ResponseEntity<T> executeRequest(RestClient client,
                                                        HttpMethod method,
                                                        String url,
                                                        Map<String, String> headers,
                                                        Map<String, ?> uriVariables,
                                                        Map<String, ?> query,
                                                        Object body,
                                                        ParameterizedTypeReference<T> responseType) {
        try {
            RestClient.RequestBodySpec request = getRequestBodySpec(client, method, url, headers, uriVariables, query, body);

            return request.retrieve()
                    .onStatus(HttpStatusCode::is4xxClientError, (req, res) -> {
                        String responseBody = new String(res.getBody().readAllBytes());
                        throw HttpClientErrorException.create(
                                res.getStatusCode(),
                                "Client Error",
                                HttpHeaders.readOnlyHttpHeaders(res.getHeaders()),
                                responseBody.getBytes(),
                                StandardCharsets.UTF_8
                        );
                    })
                    .onStatus(HttpStatusCode::is5xxServerError, (req, res) -> {
                        String responseBody = new String(res.getBody().readAllBytes());
                        throw HttpServerErrorException.create(
                                res.getStatusCode(),
                                "Server Error",
                                HttpHeaders.readOnlyHttpHeaders(res.getHeaders()),
                                responseBody.getBytes(),
                                StandardCharsets.UTF_8
                        );
                    })
                    .toEntity(responseType);
        } catch (HttpRequestException e) {
            logger.error("HTTP {} request to {} failed: {}", method, url, e.getMessage());
            throw new HttpRequestException("HTTP request failed: " + e.getMessage(), e);
        }
    }


    /**
     * 执行HTTP请求核心方法
     *
     * @param client       RestClient实例
     * @param method       HTTP方法
     * @param url          请求URL
     * @param headers      请求头Map (可为null)
     * @param uriVariables URI变量Map (可为null)
     * @param query        请求参数Map (可为null)
     * @param body         请求体对象 (可为null)
     * @param responseType 响应体类型
     * @param <T>          响应体泛型类型
     * @return 包含响应体和状态码的ResponseEntity
     * @throws HttpRequestException 当请求失败时抛出
     */
    private static <T> ResponseEntity<T> executeRequest(RestClient client,
                                                        HttpMethod method,
                                                        String url,
                                                        Map<String, String> headers,
                                                        Map<String, ?> uriVariables,
                                                        Map<String, ?> query,
                                                        Object body,
                                                        Class<T> responseType) {
        try {
            RestClient.RequestBodySpec request = getRequestBodySpec(client, method, url, headers, uriVariables, query, body);

            return request.retrieve()
                    .onStatus(HttpStatusCode::is4xxClientError, (req, res) -> {
                        String responseBody = new String(res.getBody().readAllBytes());
                        throw HttpClientErrorException.create(
                                res.getStatusCode(),
                                "Client Error",
                                HttpHeaders.readOnlyHttpHeaders(res.getHeaders()),
                                responseBody.getBytes(),
                                StandardCharsets.UTF_8
                        );
                    })
                    .onStatus(HttpStatusCode::is5xxServerError, (req, res) -> {
                        String responseBody = new String(res.getBody().readAllBytes());
                        throw HttpServerErrorException.create(
                                res.getStatusCode(),
                                "Server Error",
                                HttpHeaders.readOnlyHttpHeaders(res.getHeaders()),
                                responseBody.getBytes(),
                                StandardCharsets.UTF_8
                        );
                    })
                    .toEntity(responseType);
        } catch (HttpRequestException e) {
            logger.error("HTTP {} request to {} failed: {}", method, url, e.getMessage());
            throw new HttpRequestException("HTTP request failed: " + e.getMessage(), e);
        }
    }


    // ========== 自定义异常 ==========

    /**
     * HTTP请求异常
     */
    public static class HttpRequestException extends RuntimeException {

        /**
         * 构造方法
         *
         * @param message 错误信息
         */
        public HttpRequestException(String message) {
            super(message);
        }

        /**
         * 构造方法
         *
         * @param message 错误信息
         * @param cause   原始异常
         */
        public HttpRequestException(String message, Throwable cause) {
            super(message, cause);
        }
    }
}
